package com.slimbloody.controller;

import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import protobuf.TP;
import protobuf.TT;

import java.util.Arrays;

@Slf4j
@RestController
@RequestMapping("/repeat")
public class RepeatController {

  @PostMapping("/test")
  public void test() {
    TT.Test.Builder builder = TT.Test.newBuilder();
    for (int i = 0; i < 3; ++i) {
      TT.SubTest.Builder subBuilder = TT.SubTest.newBuilder();
      subBuilder.setI32(i);
      TT.SubTest subTest = subBuilder.build();
      builder.addSub(subTest);
    }
    TT.Test test = builder.build();
    byte[] byteArray = test.toByteArray();

    printByteArray(byteArray);
  }

  @PostMapping("/complicated")
  public void complicated() {
    TP.Test4.Builder t4b = TP.Test4.newBuilder();

    // t1
    TP.Test1.Builder t1b = TP.Test1.newBuilder();
    t1b.setA(1);
    TP.Test1 t1 = t1b.build();
    t4b.setT1(t1);

    // 交替rt1, rt2
    for (int i = 0; i < 2; ++i) {
      Integer integer = 5 + i;
      TP.Test1.Builder rt1b = TP.Test1.newBuilder();
      rt1b.setA(integer);
      TP.Test1 rt1 = rt1b.build();

      TP.Test2.Builder rt2b = TP.Test2.newBuilder();
      for (int j = 0; j < 2; ++j) {
        Integer i1 = 7 + j;
        rt2b.addB(i1);
      }
      TP.Test2 rt2 = rt2b.build();
      t4b.addRt1(rt1);
      t4b.addRt2(rt2);
    }

    // t2
    TP.Test2.Builder rt2b = TP.Test2.newBuilder();
    for (int i = 0; i < 2; ++i) {
      rt2b.addB(i);
    }
    TP.Test2 t2 = rt2b.build();
    t4b.setT2(t2);

    // t3
    TP.Test3.Builder t3b = TP.Test3.newBuilder();
    t3b.setS("9");
    for (int i = 0; i < 2; ++i) {
      Integer integer = 10 + i;
      t3b.addTi(integer);
      t3b.addTs(integer.toString());
    }
    t3b.setT(9);
    TP.Test3 t3 = t3b.build();
    t4b.setT3(t3);

    // rt3
    for (int i = 0; i < 2; ++i) {
      Integer baseI = 15 + i;
      TP.Test3.Builder rt3b = TP.Test3.newBuilder();
      rt3b.setS(baseI.toString());

      for (int j = 0; j < 2; ++j) {
        Integer baseJ = baseI + j;
        rt3b.addTi(baseJ);
        rt3b.addTs(baseJ.toString());
      }
      rt3b.setT(baseI);

      TP.Test3 rt3 = rt3b.build();
      t4b.addRt3(rt3);
    }

    // rs
    for (int i = 0; i < 2; ++i) {
      Integer integer = 20 + i;
      t4b.addRs(integer.toString());
    }
    // build
    TP.Test4 t4 = t4b.build();
    // print
    printByteArray(t4.toByteArray());
  }

  /*
在控制台输出的 [B@7aac59d5 其实并 不是你想看到的数组内容，而是 Java 默认对字节数组对象 byte[] 的 toString() 方法输出。它表示：
[B：[B 表示这是一个字节数组（byte[]）。
@：后面是一个 @ 符号。
7aac59d5：是对象的哈希码（hashCode()）的十六进制形式。
所以这串 [B@7aac59d5 只是 byte[] 对象的标识信息，并没有实际展示数组里的内容。
   */
  private static void printByteArray(byte[] byteArray) {
    System.out.println(byteArray);

    // 打印：字节数组十进制形式
    System.out.println("十进制输出: " + Arrays.toString(byteArray));

    // 打印：字节数组十六进制形式
    StringBuilder hex = new StringBuilder();
    for (byte b : byteArray) {
      hex.append(String.format("%02X ", b));
    }
    System.out.println("十六进制输出: " + hex.toString());

    // 打印：字节数组二进制形式
    StringBuilder binary = new StringBuilder();
    for (byte b : byteArray) {
      binary.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0')).append(" ");
    }
    System.out.println("二进制输出: " + binary.toString());
  }
}
